VPC CIDRブロックをRFC 1918の範囲に限定する方法 (Terraform&CloudFormation)
大家好、コンサルティング部の西野です。
AWSはVPCのCIDRブロックをRFC 1918で定められたプライベートアドレスの範囲内で設定するよう推奨しています。1
「推奨」とされていることからわかるように、プライベートアドレスレンジから外れたCIDRブロックも設定できます。 ただしこの場合、IPアドレスのバッティングにより一部の通信に支障をきたす可能性があります。 したがって、特段の事情がない限り、このプライベートアドレスレンジからVPC CIDRを設定すると良いでしょう。
本稿ではTerraformもしくはCloudFormationによって作成されるVPC CIDRブロックをこの範囲に限定する方法を記します。
最初に結論
- TerraformおよびCloudFormationでは変数ないしパラメータの検証に正規表現を利用できます。
- Terraformでは
condition
ブロック内においてcan
関数およびregex
関数を使用します。 - CloudFormationでは
Parameters
セクションのパラメータにAllowedPattern
プロパティを使用します。
Terraform
コード
variable "vpc_cidr_block" { type = string validation { condition = can(regex("(^10\\..+)|(^172\\.(1[6-9]|2[0-9]|3[0-1])\\..+)|(^192\\.168\\..+)", var.vpc_cidr_block)) error_message = "You must set the input variable \"vpc_cidr_block\" to the Private Address Space range of RFC 1918." } } resource "aws_vpc" "main" { cidr_block = var.vpc_cidr_block }
※providerの指定などは省略しています。
解説
上記コード4-7行目のvalidation
ブロックで検証をしています。このvalidation
ブロックはcondition
がfalse
として評価された場合にerror_message
で指定したエラーメッセージを表示してくれます。
can
関数およびregex
関数の組み合わせにより、vpc_cidr_blockとして与えられた変数がパターンマッチする場合にはtrue
が、そうでない場合にはfalse
が渡されます。
動かしてみる
まずはプライベートアドレスレンジに含まれているCIDRブロックを渡してみます。
問題なくterraform planに成功します。
$ terraform plan -var 'vpc_cidr_block=172.16.0.0/16' Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_vpc.main will be created + resource "aws_vpc" "main" { + arn = (known after apply) + cidr_block = "172.16.0.0/16" (省略) } Plan: 1 to add, 0 to change, 0 to destroy.
続いてプライベートアドレスレンジから外れたCIDRブロックをわたします。
$ aws-vault exec nishino-admin -- terraform plan -var 'vpc_cidr_block=172.32.0.0/16' ╷ │ Error: Invalid value for variable │ │ on main.tf line 1: │ 1: variable "vpc_cidr_block" { │ │ You must set the input variable "vpc_cidr_block" to the Private Address Space range of RFC 1918. │ │ This was checked by the validation rule at main.tf:4,3-13.
しっかりエラーを出してくれました。
検証の精度は正規表現のパターンに依存するものの、本稿の目的は達しています。2
CloudFormation
コード
AWSTemplateFormatVersion: "2010-09-09" Parameters: VpcCidr: Type: String AllowedPattern: (^10\..+)|(^172\.(1[6-9]|2[0-9]|3[0-1])\..+)|(^192\.168\..+) ConstraintDescription: You must set the parameter "VpcCidr" to the Private Address Space range of RFC 1918. Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCidr
解説
こちらはParameterのAllowedPattern
プロパティで正規表現を使用してあげるだけです。Terraformの場合と若干エスケープ処理が異なるのでご注意ください。
AllowedPattern
にマッチしないパラメータを渡した場合、スタックの作成が失敗し、エラーメッセージとしてConstraintDescription
に指定した内容が表示されます。
動かしてみる
こちらもまずはプライベートアドレスレンジに含まれているCIDRブロックを渡してみます
$ aws cloudformation create-stack \ --stack-name stack1 \ --template-body file://./vpc.yaml \ --parameters \ ParameterKey=VpcCidr,ParameterValue="10.0.0.0/16"
コマンドの実行に成功するため、少しまってから下記コマンドでリソースの状況を確認してみます。
$ aws cloudformation list-stack-resources --stack-name stack1 { "StackResourceSummaries": [ { "LogicalResourceId": "VPC", "PhysicalResourceId": "vpc-039b9c5287435705a", "ResourceType": "AWS::EC2::VPC", "LastUpdatedTimestamp": "2022-03-15T11:20:11.842000+00:00", "ResourceStatus": "CREATE_COMPLETE", "DriftInformation": { "StackResourceDriftStatus": "NOT_CHECKED" } } ] }
無事VPCが作成されています。
続いて、プライベートアドレスレンジから外れたCIDRブロックをわたします。
$ aws cloudformation create-stack \ --stack-name stack2 \ --template-body file://./vpc.yaml \ --parameters \ ParameterKey=VpcCidr,ParameterValue="192.169.0.0/16" An error occurred (ValidationError) when calling the CreateStack operation: Parameter VpcCidr failed to satisfy constraint: You must set the parameter "VpcCidr" to the Private Address Space range of RFC 1918.
こちらも想定通りエラーを出してくれました。
終わりに
構築手段としてIaCを利用する場合でも何らかの手段によってパラメータそのものの妥当性を担保する必要があります。 本稿で説明した内容がきっとその一助になるはずです。
このブログがほんの少しでも世界を良くできれば嬉しいです。
コンサルティング部の西野 (@xiyegen) がお送りしました。
参考
Terraform
- Input Variables - Configuration Language | Terraform by HashiCorp
- can - Functions - Configuration Language | Terraform by HashiCorp
- regex - Functions - Configuration Language | Terraform by HashiCorp
CloudFormation
- Using regular expressions in AWS CloudFormation templates - AWS CloudFormation
- Parameters - AWS CloudFormation
- Overview of VPCs and subnets - Amazon Virtual Private Cloud ↩
- 文字列の先頭一致のみで検証しています。もっとイケてる書き方をご存知の方はこっそり教えてくれると嬉しいです。 ↩